/*
 * Galaxium Messenger
 * 
 * Copyright (C) 2008 Paul Burton <paulburton89@gmail.com>
 * 
 * License: GNU General Public License (GPL)
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

using System;
using System.IO;
using System.Web.Services.Protocols;
using System.Xml;

using Anculus.Core;

namespace Galaxium.Protocol.Msn.Soap
{
	internal class PassportFaultFix : SoapExtension
	{
		Stream oldStream;
        Stream newStream;
		
		internal static string _redirectUrl;
		
		public override void Initialize (object initializer)
		{
			
		}

		public override object GetInitializer (LogicalMethodInfo methodInfo, SoapExtensionAttribute attribute)
		{
			return null;
		}
		
		public override object GetInitializer (Type serviceType)
		{
			return null;
		}
		
		public override Stream ChainStream (Stream stream)
        {
			oldStream = stream;
            newStream = new MemoryStream ();
            return newStream;
        }
		
		public override void ProcessMessage (SoapMessage message)
		{
			switch (message.Stage) 
            {
                case SoapMessageStage.BeforeSerialize:
                    break;
                case SoapMessageStage.AfterSerialize:
					CopyOutput (message);
                    break;
                case SoapMessageStage.BeforeDeserialize:
                    FixInput (message);
                    break;
                case SoapMessageStage.AfterDeserialize:
                    break;
                default:
                    throw new Exception("invalid stage");
            }
		}
		
		public void CopyOutput (SoapMessage message)
        {
			newStream.Position = 0;
			
            Copy (newStream, oldStream);
        }
		
        public void FixInput (SoapMessage message)
        {
			StreamReader reader = new StreamReader (oldStream);
			string xml = reader.ReadToEnd ();
			
			if (xml.Contains ("S:Fault") && (!xml.Contains ("S:Body")))
				xml = xml.Replace ("<S:Fault>", "<S:Body><S:Fault>").Replace ("</S:Fault>", "</S:Fault></S:Body>");
			
			_redirectUrl = null;
			
			if (xml.Contains ("<psf:redirectUrl>"))
			{
				int s = xml.IndexOf ("<psf:redirectUrl>") + 17;
				int len = xml.IndexOf ("</psf:redirectUrl>") - s;
				
				_redirectUrl = xml.Substring (s, len);
			}
			
			StreamWriter writer = new StreamWriter (newStream);
			writer.Write (xml);
			writer.Flush ();
			
            newStream.Position = 0;
        }
		
		void Copy (Stream from, Stream to) 
        {
            TextReader reader = new StreamReader(from);
            TextWriter writer = new StreamWriter(to);
            writer.WriteLine(reader.ReadToEnd());
            writer.Flush();
        }
	}
	
	public class PassportFaultFixAttribute : SoapExtensionAttribute
	{
		int _priority;
		
		public override Type ExtensionType
		{
			get { return typeof (PassportFaultFix); }
		}

		public override int Priority
		{
			get { return _priority; }
			set { _priority = value; }
		}
	}
}